﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using CastleOfTheDisillusioned.Location;
using CastleOfTheDisillusioned.Overworld;

namespace CastleOfTheDisillusioned.Location.Maps {
	abstract partial class Map : BoundingBox {

		#region Cell Accessor Shortcuts
		public List<Cell> Cells = new List<Cell>();

		public virtual List<Tile> Tiles {
			get {
				List<Tile> AllTiles = new List<Tile>();
				foreach (Cell c in Cells){
					AllTiles.AddRange(c.Tiles);
				}
				return AllTiles;
			}
		}

		public virtual List<Enemy> Enemies {
			get {
				List<Enemy> AllEnemies = new List<Enemy>();
				foreach (Cell c in Cells) {
					AllEnemies.AddRange(c.Enemies);
				}
				return AllEnemies;
			}
		}

		public virtual List<Entity> Entities {
			get {
				List<Entity> AllEntities = new List<Entity>();
				foreach (Cell c in Cells) {
					AllEntities.AddRange(c.Entities);
				}
				return AllEntities;
			}
		}
		#endregion

		public SpawnInfo StartingPosition = null;

		public virtual void Draw() {
			foreach (Tile t in Tiles) {
				t.Draw();
			}

			foreach (Enemy e in Enemies) {
				e.Draw();
			}

			foreach (Entity e in Entities) {
				e.Draw();
			}
		}

		public virtual void Update() {
			foreach (Cell c in Cells) {
				c.Update();
			}

			//Leaving the map
			Player player = Location_State.CurrentPlayer;
			if (player.X < this.X) {
				Location_State.LeaveLocation();
			} else if (player.X + player.Width > Width + X) {
				Location_State.LeaveLocation();
				Overworld_State.CurrentRealm.Explore();
			}
		}

		public bool PlaceFree(Entity ent, double X, double Y) {
			BoundingBox p = ent.Copy();
			p.X = X;
			p.Y = Y;

			foreach (Tile t in Tiles) {
				if (p.CollidesWith(t) && t.Solid) {
					if (t.Fallthrough) {
						if (ent.Y + ent.Height < t.Y) {
							return false; //Only collide if entity was previously above tile.
						}
					} else {
						//Not fallthrough, we collided with something
						return false;
					}
				}
			}

			return true;
		}

		public List<Enemy> GetEnemies() {
			return Enemies;
		}

		public List<Entity> GetEntities() {
			return Entities;
		}

		protected double GetX() {
			//Just find the leftmost side, and return that.
			double FarthestLeft = Cells[0].Left;
			foreach (Cell cell in Cells) {
				if (cell.Left < FarthestLeft) {
					FarthestLeft = cell.Left;
				}
			}
			return FarthestLeft;
		}

		protected double GetY() {
			//Just find the topmost side, and return that.
			double FarthestUp = Cells[0].Top;
			foreach (Cell cell in Cells) {
				if (cell.Top < FarthestUp) {
					FarthestUp = cell.Top;
				}
			}
			return FarthestUp;
		}

		protected double GetWidth() {
			double FarthestRight = 0;
			foreach (Cell cell in Cells) {
				if (cell.Right > FarthestRight) {
					FarthestRight = cell.Right;
				}
			}
			return FarthestRight - GetX();
		}

		protected double GetHeight() {
			double FarthestDown = 0;
			foreach (Cell cell in Cells) {
				if (cell.Bottom > FarthestDown) {
					FarthestDown = cell.Bottom;
				}
			}
			return FarthestDown - GetY();
		}
	}
}
